package com.daxia.bumall.service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.daxia.bumall.common.ProductCategoryStatus;
import com.daxia.bumall.dao.ProductCategoryDAO;
import com.daxia.bumall.dao.ProductCategoryTagDAO;
import com.daxia.bumall.dto.ProductCategoryDTO;
import com.daxia.bumall.model.ProductCategory;
import com.daxia.bumall.model.ProductCategoryTag;
import com.daxia.bumall.support.Page;
import com.daxia.bumall.util.BeanMapper;

@Service
public class ProductCategoryService {
	private static Logger logger = Logger.getLogger(ProductCategoryService.class);
	
	@Autowired
	private ProductCategoryDAO productCategoryDAO;
	@Autowired
	private ProductCategoryTagDAO tagDAO;
	
	public List<ProductCategoryDTO> find(ProductCategoryDTO query, Page page) {
		List<ProductCategory> models = productCategoryDAO.find(query, page);
		List<ProductCategoryDTO> dtos = toDTOs(models);
		return dtos;
	}
	
	public List<ProductCategoryDTO> findAll() {
		return this.find(new ProductCategoryDTO(), null);
	}
	
	public List<ProductCategoryDTO> find(int count) {
		Page page = new Page();
		page.setPage(1);
		page.setPageSize(count);
		return this.find(new ProductCategoryDTO(), page);
	}
	
	public Long create(ProductCategoryDTO dto) {
		ProductCategory model = new ProductCategory();
		toModel(model, dto);
		return productCategoryDAO.create(model);
	}
	
	public ProductCategoryDTO load(Long id) {
	    ProductCategory model = productCategoryDAO.load(id);
	    return toDTO(model);
    }

	public void updateAllFields(ProductCategoryDTO dto) {
		ProductCategory model = productCategoryDAO.load(dto.getId());
		toModel(model, dto);
		productCategoryDAO.update(model);
    }

	public void deleteByIds(Long[] ids) {
		if (ids != null) {
			for (Long id : ids) {
				productCategoryDAO.deleteById(id);
			}
		}
    }
	
	public void deleteById(Long id) {
		this.deleteByIds(new Long[] {id});
	}

	public ProductCategoryDTO findOne(ProductCategoryDTO query) {
		ProductCategory model = productCategoryDAO.findOne(query);
		return toDTO(model);
	}
	
	private List<ProductCategoryDTO> toDTOs(List<ProductCategory> models) {
		if (CollectionUtils.isEmpty(models)) {
			return new ArrayList<ProductCategoryDTO>(0);
		}
		List<ProductCategoryDTO> dtos = new ArrayList<ProductCategoryDTO>(models.size());
		for (ProductCategory model : models) {
	        ProductCategoryDTO dto = toDTO(model);
	        dtos.add(dto);
        }
	    return dtos;
    }
    
    private ProductCategoryDTO toDTO(ProductCategory model) {
		if (model == null) {
			return null;
		}
		ProductCategoryDTO dto = BeanMapper.map(model, ProductCategoryDTO.class);
		
		return dto;
	}
	
	private void toModel(ProductCategory model, ProductCategoryDTO dto) {
		BeanMapper.copy(dto, model);
    }
	
	@SuppressWarnings("unused")
	private List<ProductCategory> toModels(List<ProductCategoryDTO> dtos) {
		if (CollectionUtils.isEmpty(dtos)) {
			return new ArrayList<ProductCategory>(0);
		}
		List<ProductCategory> models = new ArrayList<ProductCategory>(dtos.size());
		for (ProductCategoryDTO dto : dtos) {
	        ProductCategory model = new ProductCategory();
	        toModel(model, dto);
	        models.add(model);
        }
		return models;
	}

	public List<ProductCategoryDTO> findRoot(int size) {
		ProductCategoryDTO q = new ProductCategoryDTO();
		q.setFindRoot(true);
		Page page = new Page();
		page.setPageSize(size);
		return this.find(q, page);
	}
	
	public List<ProductCategoryDTO> findAllRoot() {   //找到所有的根结点
		ProductCategoryDTO q = new ProductCategoryDTO();
		q.setFindRoot(true);
		return this.find(q, null);
	}

	public ProductCategoryDTO findByName(String name) {
		ProductCategoryDTO query = new ProductCategoryDTO();
		query.setName(name);
		return this.findOne(query);
	}

	@Transactional
	public void doUpload(MultipartFile mf) throws Exception {
		Workbook book = WorkbookFactory.create(mf.getInputStream());
		Sheet sheet = book.getSheetAt(0);
		// 获取左上角的单元格
		int count = 0;
		Iterator<Row> iterable = sheet.rowIterator();
		iterable.next();
		String lastLevel1 = "";
		String lastLevel2 = "";
		String lastLevel3 = "";
		while (iterable.hasNext()) {
			Row row = iterable.next();
			if (row.getCell(0) != null && StringUtils.isNotBlank(row.getCell(0).getStringCellValue().trim())) {
				lastLevel1 = row.getCell(0).getStringCellValue().trim();
			}
			if (row.getCell(1) != null && StringUtils.isNotBlank(row.getCell(1).getStringCellValue().trim())) {
				lastLevel2 = row.getCell(1).getStringCellValue().trim();
			}
			if (row.getCell(2) != null && StringUtils.isNotBlank(row.getCell(2).getStringCellValue().trim())) {
				lastLevel3 = row.getCell(2).getStringCellValue().trim();
			}
			
			if (logger.isDebugEnabled()) {
				logger.debug("lastLevel1: " + lastLevel1 + ", lastLevel2: " + lastLevel2 + ", lastLevel3: " + lastLevel3);
			}
			ProductCategory level1 = this.findByName(lastLevel1);
			if (level1 == null) {
				if (logger.isDebugEnabled()) {
					logger.debug("find by LastLevel1 " + lastLevel1 + " is null");
				}
				level1 = new ProductCategory();
				level1.setLevel(1);
				level1.setName(lastLevel1);
				level1.setStatus(ProductCategoryStatus.Active.getValue());
				Long id = productCategoryDAO.create(level1);
				level1 = productCategoryDAO.load(id);
			}
			
			ProductCategory level2 = this.findByName(lastLevel2);
			if (level2 == null) {
				level2 = new ProductCategory();
				level2.setLevel(2);
				level2.setName(lastLevel2);
				level2.setStatus(ProductCategoryStatus.Active.getValue());
				level2.setParentCategory(level1);
				Long id = productCategoryDAO.create(level2);
				level2 = productCategoryDAO.load(id);
			}
			
			ProductCategory level3 = this.findByName(lastLevel3);
			if (level3 == null) {
				level3 = new ProductCategory();
				level3.setLevel(3);
				level3.setName(lastLevel3);
				level3.setStatus(ProductCategoryStatus.Active.getValue());
				level3.setParentCategory(level2);
				Long id = productCategoryDAO.create(level3);
				level3 = productCategoryDAO.load(id);
			}

			if (row.getCell(3) == null || StringUtils.isBlank(row.getCell(3).getStringCellValue().trim())) {
				if (logger.isDebugEnabled()) {
					logger.debug("no tag");
				}
				continue;
			}
			
			String tagName = row.getCell(3).getStringCellValue().trim();
			String tagValues = row.getCell(4) == null ? null : row.getCell(4).getStringCellValue().trim();
			ProductCategoryTag t = tagDAO.findByProductCategoryAndName(level3.getId(), tagName);
			if (t != null) {
				continue;
			}
			
			t = new ProductCategoryTag();
			t.setProductCategory(level3);
			t.setName(tagName);
			if (StringUtils.isNotBlank(tagValues)) {
				tagValues = tagValues.replace("、", ",").replace("，", ",").replace(" ", ",");
			}
			t.setValues(tagValues);
			tagDAO.create(t);
		}
			
	
	}

	public ProductCategoryDTO findOne(String level1Name, String level2Name,	 String level3Name) {
		if (StringUtils.isBlank(level1Name) || StringUtils.isBlank(level2Name) || StringUtils.isBlank(level3Name)) {
			return null;
		}
		ProductCategoryDTO query = new ProductCategoryDTO();
		query.setNames(new String[] {level1Name, level2Name, level3Name});
		return this.findOne(query);
	}
}
